﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using Didaku.Collections;
using Didaku.QEngine.Common.Abstracts.Entities;
using Didaku.QEngine.Common.Entities;
using Didaku.QEngine.Common.Wrapper.Engine;
using Didaku.QEngine.Common.Wrapper.Engine.Groups;
using NLog;

namespace Didaku.QEngine.Demo
{
    /// <summary>模拟生成一个Department,Department同时也是一个描述网点有关队列元素的集合。
    /// </summary>
    internal class DepartmentMock
    {
        private static readonly Logger _Logger = LogManager.GetCurrentClassLogger();

        private static readonly UtilityRandom _Random = new UtilityRandom();

        private static SerializableMap<string, CardCategory> _CardTypes;
        private static SerializableMap<string, Staff> _Staffs;
        private static SerializableMap<string, District> _Districts;
        private static SerializableMap<string, Counter> _Counters;
        private static SerializableMap<string, BusinessType> _BusinessTypes;

        private static SerializableMap<string, ServiceQueue> _ServiceQueues;
        private static SerializableMap<string, ServiceLogic> _ServiceLogic;

        /// <summary>获取一个模拟的Department。
        /// </summary>
        /// <returns></returns>
        public static DepartmentInfo Get()
        {
            _Logger.Trace("模拟一个网点的信息集合");
            var department = new Department
            {
                //队列元素
                BusinessTypeMap = GetBusinessTypeMap(),
                CounterMap = GetCounterMap(),
                DistrictMap = GetDistrictMap(),
                StaffMap = GetStaffMap(),
                CardCategoryMap = GetCardTypeMap(),

                //服务队列
                ServiceQueueMap = GetServiceQueueMap(),
                ServiceLogicMap = GetServiceLogicMap()
            };
            foreach (var logicPair in department.ServiceLogicMap)
            {
                ServiceQueue superqueue = logicPair.Value[0][0];
                //department.ServiceQueueMap.Add(superqueue.Id, superqueue);
            }
            return department;
        }

        private static SerializableMap<string, CardCategory> GetCardTypeMap()
        {
            _CardTypes = new SerializableMap<string, CardCategory>();
            for (int i = 1; i <= 8; i++)
            {
                var cardType = new CardCategory
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = i + "级客户"
                };
                cardType.Description = cardType.Name;
                _CardTypes.Add(cardType.Id, cardType);
            }
            return _CardTypes;
        }

        private static SerializableMap<string, Staff> GetStaffMap()
        {
            _Staffs = new SerializableMap<string, Staff>();
            for (int i = 1; i <= 16; i++)
            {
                var staff = new Staff
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "员工" + i
                };
                _Staffs.Add(staff.Id, staff);
            }
            return _Staffs;
        }

        private static SerializableMap<string, District> GetDistrictMap()
        {
            _Districts = new SerializableMap<string, District>();
            for (int i = 1; i <= 4; i++)
            {
                var district = new District
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "分区" + i
                };
                _Districts.Add(district.Id, district);
            }
            return _Districts;
        }

        private static SerializableMap<string, Counter> GetCounterMap()
        {
            _Counters = new SerializableMap<string, Counter>();
            for (int i = 1; i <= 24; i++)
            {
                var counter = new Counter
                {
                    Id = Guid.NewGuid().ToString(),
                    Index = i,
                    Name = "柜台" + i
                };
                _Counters.Add(counter.Id, counter);
            }
            return _Counters;
        }

        private static SerializableMap<string, BusinessType> GetBusinessTypeMap()
        {
            _BusinessTypes = new SerializableMap<string, BusinessType>();
            for (int i = 1; i <= 12; i++)
            {
                var businessType = new BusinessType
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "业务" + i
                };
                _BusinessTypes.Add(businessType.Id, businessType);
            }
            return _BusinessTypes;
        }

        private static SerializableMap<string, ServiceQueue> GetServiceQueueMap()
        {
            _ServiceQueues = new SerializableMap<string, ServiceQueue>();
            const string abcd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            for (int i = 0; i < abcd.Length; i++)
            {
                var queue = new ServiceQueue
                {
                    Id = Guid.NewGuid().ToString(),
                    Name = "队列" + (i + 1)
                };
                queue.Number = queue.CallHead;
                queue.TicketEndNumber = 123;
                queue.TicketLength = 4;
                queue.TicketMaxCount = 234;
                queue.TicketStartNumber = 1;
                queue.CallHead = abcd.Substring(i, 1);

                int n = _Random.Next(-(_CardTypes.Count), _CardTypes.Count);
                if (n > 0)
                    queue.Elements.Add(_CardTypes.Values.ElementAt(n));

                n = _Random.Next(-(_Staffs.Count), _Staffs.Count);
                if (n > 0)
                    queue.Elements.Add(_Staffs.Values.ElementAt(n));

                n = _Random.Next(-(_Districts.Count), _Districts.Count);
                if (n > 0)
                    queue.Elements.Add(_Districts.Values.ElementAt(n));

                n = _Random.Next(-(_Counters.Count), _Counters.Count);
                if (n > 0)
                    queue.Elements.Add(_Counters.Values.ElementAt(n));

                n = _Random.Next(-(_BusinessTypes.Count), _BusinessTypes.Count);
                if (n > 0)
                    queue.Elements.Add(_BusinessTypes.Values.ElementAt(n));

                _ServiceQueues.Add(queue.Id, queue);
            }
            return _ServiceQueues;
        }

        private static SerializableMap<string, ServiceLogic> GetServiceLogicMap()
        {
            _ServiceLogic = new SerializableMap<string, ServiceLogic>();

            var booking = new BookingQueueGroup() { Name = "预约队列组" };
            foreach (var pair in _Counters)
            {
                var logic = new ServiceLogic {Counter = pair.Value};
                var super = new SuperQueueGroup(pair.Value)
                {
                    Name = "超级队列组"
                };
                logic.Add(super);
                logic.Add(booking);
                int groupCount = _Random.Next(1, 6);
                for (int i = 0; i < groupCount; i++)
                {
                    var g = new GenericQueueGroup() {Name = "普通队列组"};
                    int queueCount = _Random.Next(1, _ServiceQueues.Count/2);
                    int[] seq = _Random.GetUnrepeatInts(queueCount, 0, _ServiceQueues.Count);
                    g.AddRange(seq.Select(t => _ServiceQueues.Values.ElementAt(t)));
                    logic.Add(g);
                }
                _ServiceLogic.Add(pair.Key, logic);
            }

            string sera = UtilitySerialize.Serialize(_ServiceLogic);
            const string path = "D:\\ServiceLogic.xml";
            if (File.Exists(path))
                File.Delete(path);
            File.WriteAllText(path, sera, Encoding.Unicode);

            return _ServiceLogic;
        }

        private class Department : DepartmentInfo
        {
            public Department()
            {
                Id = Guid.NewGuid().ToString();
                AreaCode = "00200";
                Name = "力合银行将台路支行";
                Number = "987321";
            }

            #region Overrides of DepartmentInfo

            /// <summary>
            ///     当前网点的分区字典。
            /// </summary>
            public override SerializableMap<string, District> DistrictMap { get; set; }

            /// <summary>
            ///     当前网点的柜台字典。
            /// </summary>
            public override SerializableMap<string, Counter> CounterMap { get; set; }

            /// <summary>
            ///     当前网点的业务类型字典。
            /// </summary>
            public override SerializableMap<string, BusinessType> BusinessTypeMap { get; set; }

            /// <summary>
            ///     当前网点的员工字典。
            /// </summary>
            public override SerializableMap<string, Staff> StaffMap { get; set; }

            /// <summary>
            ///     当前网点的工作流字典。
            /// </summary>
            public override SerializableMap<string, Workflow> WorkflowMap { get; set; }

            /// <summary>
            ///     当前网点的卡片类别字典。
            /// </summary>
            public override SerializableMap<string, CardCategory> CardCategoryMap { get; set; }

            /// <summary>
            /// 当前网点的服务队列字典。Key是队列的Id。
            /// </summary>
            public override SerializableMap<string, ServiceQueue> ServiceQueueMap { get; set; }

            /// <summary>
            /// 当前网点的服务逻辑字典。Key是柜台的Id，Value指的是服务逻辑。
            /// </summary>
            public override SerializableMap<string, ServiceLogic> ServiceLogicMap { get; set; }

            #endregion
        }
    }
}